﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;

namespace SMARTMobile.WinPhone
{
    public enum DataSourceType
    {
        Http,
        IsolatedStorage,
        SDF,
        Text
    }

    public enum AuthenticationType
    {
        Basic
    }

    [XmlRoot("DataSourceMap")]
    public class DataSourcesConfiguration
    {
        [XmlIgnore]
        private IDictionary<string, DataSource> _sourceMap;

        [XmlIgnore]
        private IDictionary<string, Endpoint> _endPointMap;

        [XmlArray(ElementName = "DataSources")]
        [XmlArrayItem(ElementName = "Source")]
        public List<DataSource> DataSources
        {
            get; set;
        }

        [XmlArray(ElementName = "Endpoints")]
        [XmlArrayItem(ElementName = "Endpoint")]
        public List<Endpoint> Endpoints
        {
            get; set;
        }

        internal void Prepare()
        {
            this._endPointMap = Endpoints.ToDictionary(ep => ep.Name);
            foreach (var dataSource in DataSources)
            {
                string key = dataSource.EndpointName ?? dataSource.Name;
                if (!this._endPointMap.ContainsKey(key))
                    continue;

                dataSource.Endpoint = this._endPointMap[key];
            }

            this._sourceMap = DataSources.ToDictionary(s => s.Name);
        }

        public DataSource FindSource(string name)
        {
            DataSource result;
            this._sourceMap.TryGetValue(name, out result);

            return result;
        }

        public Uri FindEndpoint(string endpointName)
        {
            Endpoint result;
            this._endPointMap.TryGetValue(endpointName, out result);

            return (null == result) ? null : result.GetUri();
        }
    }

    [XmlRoot("DataSourceMap")]
    public class DataSourceConfiguration
    {
        [XmlIgnore]
        private IDictionary<string, DataSource> _sourceMap;

        [XmlIgnore]
        private IDictionary<string, Endpoint> _endPointMap;

        [XmlArray(ElementName = "DataSources")]
        [XmlArrayItem(ElementName = "Source")]
        public List<DataSource> DataSources
        {
            get;
            set;
        }

        [XmlArray(ElementName = "Endpoints")]
        [XmlArrayItem(ElementName = "Endpoint")]
        public List<Endpoint> Endpoints
        {
            get;
            set;
        }

        public DataSource FindSource(string name)
        {
            DataSource result;
            _sourceMap.TryGetValue(name, out result);
            return result;
        }

        public Uri FindEndpoint(string endpointName)
        {
            Endpoint result;
            this._endPointMap.TryGetValue(endpointName, out result);

            return (null == result) ? null : result.GetUri();
        }

        internal void Prepare()
        {
            this._endPointMap = Endpoints.ToDictionary(ep => ep.Name);
            foreach (var dataSource in DataSources)
            {
                string key = dataSource.EndpointName ?? dataSource.Name;
                if (!this._endPointMap.ContainsKey(key))
                    continue;

                dataSource.Endpoint = this._endPointMap[key];
            }

            this._sourceMap = DataSources.ToDictionary(s => s.Name);
        }
    }

    [XmlRoot("Source")]
    public class DataSource
    {
        [XmlAttribute("name")]
        public string Name { get; set; }

        [XmlAttribute("type")]
        public DataSourceType Type { get; set; }

        [XmlAttribute("element")]
        public string Element { get; set; }

        [XmlAttribute("endpoint")]
        public string EndpointName { get; set; }

        [XmlElement("param")]
        public List<Parameter> Paramaters { get; set; }

        [XmlIgnore]
        public Endpoint Endpoint { get; set; }
    }

    [XmlRoot("Endpoint")]
    public class Endpoint
    {
        [XmlAttribute("name")]
        public string Name { get; set; }

        [XmlAttribute("uri")]
        public string Uri { get; set; }

        public Uri GetUri()
        {
            return new Uri(this.Uri, UriKind.RelativeOrAbsolute);
        }
    }

    [XmlRoot("param")]
    public class Parameter
    {
        [XmlAttribute("name")]
        public string Name { get; set; }

        [XmlAttribute("value")]
        public string Value { get; set; }
    }
}
